use std::env;
struct Cat {
    sample_id: String,
    sample_name: String,
    sample_num:String,
    sample_weight:f32,
    content01:f32,
    content02:f32,
}
//         print(row)
//         id1=row[0]
//         oldwt=row[3]
//         wt=oldwt*wtb
//         old01=row[6]
//         old02=row[7]
//         old03=row[8]
// // -*- coding: utf-8 -*-
// import sqlite3
// import datetime
// // CREATE TABLE Result (
// //     sample_id     DATETIME PRIMARY KEY,
// //     sample_name   TEXT,
// //     sample_num    TEXT,
// //     sample_weight REAL     NOT NULL,
// //     SampleUnit   TEXT,
// //     FluxWeight   REAL,
// //     content01    REAL,
// //     content02    REAL,
// //     Content03    REAL,
// //     Area01       REAL,
// //     Area02       REAL,
// //     Area03       REAL,
// //     Channel      INTEGER,
// //     Area1        REAL,
// //     Area2        REAL,
// //     Area3        REAL,
// //     Area4        REAL,
// //     Area5        REAL,
// //     Area6        REAL,
// //     Content1     REAL,
// //     Content2     REAL,
// //     Content3     REAL,
// //     Content4     REAL,
// //     Content5     REAL,
// //     Content6     REAL,
// //     Content10    REAL,
// //     Content20    REAL,
// //     Content30    REAL,
// //     Content40    REAL,
// //     Content50    REAL,
// //     Content60    REAL,
// //     MethodName   TEXT,
// //     UserName     TEXT,
// //     ResultUnit1  TEXT,
// //     ResultUnit2  TEXT
// // );
// // sample_id     DATETIME PRIMARY KEY
// //                           REFERENCES Result (sample_id) ON UPDATE CASCADE
// //                                                        ON DELETE CASCADE,
// //     Channels     BLOB,
// //     Factors      BLOB,
// //     Averages     BLOB,
// //     LineFactor   REAL,
// //     DataTime     BLOB,
// //     DataChannel1 BLOB,
// //     DataChannel2 BLOB,
// //     DataChannel3 BLOB,
// //     DataChannel4 BLOB,
// //     DataChannel5 BLOB,
// //     DataChannel6 BLOB
// fn copyOne2(conn,id1,id2){
//     c = conn.cursor();
//     c.execute("select * from data where sample_id >? and sample_id<?" ,(id1,minuteJ1(id1)));
//     sn=None;
//     for row in c{
//         id1=row[0]
//         Averages=row[3]
//         DataTime=row[5]
//         DataChannel1=row[6]
//         DataChannel2=row[7]
//         DataChannel3=row[8]
//         DataChannel4=row[9]
//         DataChannel5=row[10]
//         DataChannel6=row[11]
//         break
//     }
//     c.execute("select * from result where sample_id ='"+id1+"'");
//     sn=None；
//     for row in c{
//         sample_weight =row[3]
//         content01=row[6]
//         content02=row[7]
//         Content03=row[8]
//         break
//     }
//     c.execute("select * from result where sample_id >? and sample_id<?" ,(id2,minuteJ1(id2)));
//     for row in c{
//         id2=row[0]
//         break    
//     }    
//     print(id1,id2)；
//     c.execute("update data set Averages=?,DataTime=?,DataChannel1=?,DataChannel2=?,DataChannel3=?,DataChannel4=?,DataChannel5=?,DataChannel6=? where sample_id=?",(Averages,DataTime,DataChannel1,DataChannel2,DataChannel3,DataChannel4,DataChannel5,DataChannel6, id2));
//     print((sample_weight,content01,content02,id2))
//     c.execute("update result set sample_weight=?, content01=?, content02=? where sample_id=?"
//         ,(sample_weight*1.005,content01/1.005,content02/1.005,id2))
//     conn.commit()
//     conn.close()

fn get_one(conn:rusqlite::Connection,id1:String)->(String,i32) {
    println!("=========");
    let j1=minute_j1(id1.clone());
    println!("{},{}",id1,j1);
    let mut stmt = conn.prepare(
        "select * from result where sampleid>=? and sampleid<=?",
    ).expect("error prepare");
    let cats = stmt.query_map(&[&id1,&j1], |row| {
        Ok(Cat {
            sample_id: row.get(0).expect("error get"),
            sample_name: row.get(1).expect("error get"),
            sample_num: row.get(2).expect("error get"),
            sample_weight: row.get(3).expect("error get"),
            content01: row.get(6).expect("error get"),
            content02 : row.get(7).expect("error get"),

        })
    }).expect("error query");
    for row in cats{
        let o=row.unwrap();
        println!("<id{},{}",o.sample_num,o.sample_id);
        return (o.sample_id,o.sample_num.parse::<i32>().unwrap());
    }
    return (String::from(""),0);
}
pub fn change_one(conn:&rusqlite::Connection,id1:String,wtb:f32){
    let j1=minute_j1(id1.clone());
    println!("{},{}",id1,j1);
    let mut stmt = conn.prepare(
        "select * from result where sampleid>=? and sampleid<=?",
    ).expect("error prepare");
    let cats = stmt.query_map(&[&id1,&j1], |row| {
         Ok(Cat {
            sample_id: row.get(0).expect("error get"),
            sample_name: row.get(1).expect("error get"),
            sample_num: row.get(2).expect("error get"),
            sample_weight: row.get(3).expect("error get"),
            content01: row.get(6).expect("error get"),
            content02 : row.get(7).expect("error get"),
         })
    }).expect("error query");
    let mut o=Cat{sample_id:String::from("")
    ,sample_name:String::from("")
    ,sample_num:String::from(""),sample_weight:0.0
        ,content01:0.0,content02:0.0};
    for row in cats{
        o=row.unwrap();
        break;
    }
    println!("=========");
    println!("id={}",o.sample_id);
    if o.sample_id==""{ 
        println!("not found");
        return;
    }
    let wt=(o.sample_weight *wtb).to_string();
    let c01=(o.content01/wtb).to_string();
    let c02=(o.content02/wtb).to_string();
    //, (wt,old01/wtb,old02/wtb,id1))",
    conn.execute(
            "update result set sampleweight=?, content01=?, content02=? where sampleid=?" 
           ,&[&wt,&c01,&c02,&o.sample_id]
        ).expect("execute error");
}
fn copy_one(conn:&rusqlite::Connection,id1:String,id2:String){
    let j1=minute_j1(id1.clone());
    println!("{},{}",id1,j1);
    let mut stmt = conn.prepare(
        "select * from result where sampleid>=? and sampleid<=?",
    ).expect("error prepare");
    let cats = stmt.query_map(&[&id1,&j1], |row| {
         Ok(Cat {
            sample_id: row.get(0).expect("error get"),
            sample_name: row.get(1).expect("error get"),
            sample_num: row.get(2).expect("error get"),
            sample_weight: row.get(3).expect("error get"),
            content01: row.get(6).expect("error get"),
            content02 : row.get(7).expect("error get"),
         })
    }).expect("error query");
    let mut o=Cat{sample_id:String::from("")
    ,sample_name:String::from("")
    ,sample_num:String::from(""),sample_weight:0.0
        ,content01:0.0,content02:0.0};
    for row in cats{
        o=row.unwrap();
        break;
    }
    println!("=========");
    println!("id={}",o.sample_id);
    if o.sample_id==""{ 
        println!("not found");
        return;
    }
    let wt=(o.sample_weight ).to_string();
    let c01=(o.content01).to_string();
    let c02=(o.content02).to_string();
    //, (wt,old01/wtb,old02/wtb,id1))",
    conn.execute(
            "update result set sampleweight=?, content01=?, content02=? where sampleid=?" 
           ,&[&wt,&c01,&c02,&o.sample_id]
        ).expect("execute error");
}
fn del_one(conn:&rusqlite::Connection,id1:String){
    let j1=minute_j1(id1.clone());
    println!("{},{}",id1,j1);
    let mut stmt = conn.prepare(
        "select * from result where sampleid>=? and sampleid<=?",
    ).expect("error prepare");
    let cats = stmt.query_map(&[&id1,&j1], |row| {
        Ok(Cat {
            sample_id: row.get(0).expect("error get"),
            sample_name: row.get(1).expect("error get"),
            sample_num: row.get(2).expect("error get"),
            sample_weight: row.get(3).expect("error get"),
            content01: row.get(6).expect("error get"),
            content02 : row.get(7).expect("error get"),
        })
    }).expect("error query");
    let mut id=String::from("");
    let mut sn=0;
    for row in cats{
        let o=row.unwrap();
        println!("<id{},{}",o.sample_num,o.sample_id);
        id=o.sample_id;
        sn=o.sample_num.parse::<i32>().unwrap();
        break;
    }
    println!("=========");
    println!("{}",id);
    println!("{}",sn);
    if id==""{ 
        println!("not found");
        return;
    }
    conn.execute(
            "delete  from result where sampleid=?",
           &[&id]
        ).expect("execute error");
    let mut stmt = conn.prepare(
        "select * from result where sampleid>?",
    ).expect("prepare error");

    let cats = stmt.query_map(&[&id], |row| {
         Ok(Cat {
            sample_id: row.get(0).expect("error get"),
            sample_name: row.get(1).expect("error get"),
            sample_num: row.get(2).expect("error get"),
            sample_weight: row.get(3).expect("error get"),
            content01: row.get(6).expect("error get"),
            content02 : row.get(7).expect("error get"),
        })
    }).expect("query error");
    let mut sn1=sn;
    for row in cats{
        let o=row.unwrap();
        let sn1_str=sn1.to_string();
        conn.execute(
            "update result set samplenum=? where sampleid=?",
           &[&sn1_str,&o.sample_id]
        ).expect("update error");
        sn1+=1;
    }
}
// fn changeOne(conn,id2,wtb,constr){
//     //print(conn)
//     if r"CS\data" in constr:
//         isCS=True
//     else:
//         isCS=False
//     c = conn.cursor()
//     cmd="select * from result where sample_id>='%s' and sample_id<'%s'" % (id2,minuteJ1(id2))
//     print(cmd)
//     c.execute(cmd)
//     print(c);    
//     for row in c:
//         print(row)
//         id1=row[0]
//         oldwt=row[3]
//         wt=oldwt*wtb
//         old01=row[6]
//         old02=row[7]
//         old03=row[8]
//         break
//     print(oldwt,old01,old02,old03)
//     try:
//         c.execute("""update result set sample_weight=?, content01=?, content02=? where sample_id=?""" , (wt,old01/wtb,old02/wtb,id1))
//     except  TypeError as e:
//         print(e)
//         print("content01 error")
//     conn.commit()
//     conn.close()
// }
// fn rename_day_before_one(conn:rusqlite::Connection,id1:String) -> rusqlite::Result<()> {//从一天开始到该时间
   
//    let dbegin=day_begin(id1.clone());
//    println!("{}->{}",id1,dbegin);
//    conn.execute(
//             "update  result set samplename='' where sampleid<? and sampleid>?",
//            &[&id1, &dbegin]
//         )?;
//    Ok(())
// }
// fn rename_all(conn:rusqlite::Connection,id1:String) -> rusqlite::Result<()>{//该时间之前
//     conn.execute(
//             "update result set samplename=' '  where sampleid<?",
//            &[&id1,]
//         )?;
//     Ok(())
// }
// fn db() -> rusqlite::Result<()> {
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     //let r=rename_day_before_one(conn,String::from("2021-06-29 13:52"));
//     let r=del_one(&conn,String::from("2020-06-29 13:25"));
//     println!("{:?}",r);
//     // changeOne(conn,'2021-06-29 13:52',1/1.005,constr)
//     Ok(())
// }
// fn day_begin(s:String) ->String {//'2016-12-23 14:59'    
//     let tokens=s.split(" ");
//     let mut r=String::new();
//     for token in tokens{
//         println!("{:?}",token );
//         r.push_str(token);
//         break;//first token
//     }
//     r.push_str(" 00:00");
//     return r;   
// } 
fn minute_j1(id1:String) ->String {
    let tokens=id1.split(" ");
    let a:Vec<&str>=tokens.collect();
    let d=a[0];
    let t=a[1];
    println!("{},{}",d,t);
    // let tokens=d.split("-");
    // let a:Vec<&str>=tokens.collect();
    // let y=a[0];
    // let mon=a[1];
    // let day=a[2];
    // println!("{},{},{}",y,mon,d);
    let tokens=t.split(":");
    let a:Vec<&str>=tokens.collect();
    let mut h=a[0].parse::<i32>().unwrap();
    let mut min=a[1].parse::<i32>().unwrap();
    if min+1==60{
        h=h+1;
        min=0;
    }
    else{
        min=min+1;
    }
    println!("{},{}",h,min);
    return format!("{} {}:{}",d,h,min);
}

// fn test_main(){
//    let s=String::from("2020-06-29 13:25");
//    let s1=s.clone();
//    let j1=minute_j1(s1);
//    let s2=s.clone();
//    let b1=day_begin(s2);
//    println!("{}->{}",s,j1);
//    println!("{}->{}",s,b1);
// }
// fn do_main() -> rusqlite::Result<()> {
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     let r=rename_day_before_one(conn,String::from("2021-08-31 14:11"));
//     println!("{:?}",r);
//     Ok(())
// }
// fn do_main2() -> rusqlite::Result<()> {
//     let constr=String::from(".\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     let mut stmt = conn.prepare(
//         "select * from result order by sampleid  desc limit 3",
//     )?;
//     let cats = stmt.query_map([], |row| {
//          Ok(Cat {
//             sample_id: row.get(0).expect("error get"),
//             sample_name: row.get(1).expect("error get"),
//             sample_num: row.get(2).expect("error get"),
//             sample_weight: row.get(3).expect("error get"),
//             content01: row.get(6).expect("error get"),
//             content02 : row.get(7).expect("error get"),
//         })
//     })?;
//     for row in cats{
//         let o=row.unwrap();
//         println!("id={};name={};sn={}",o.sample_id,o.sample_name,o.sample_num);
//     }
//     Ok(())
// }
// pub fn main0(){
//     let constr=String::from(".\\data.db");
//     let conn = rusqlite::Connection::open(constr).expect("open error");
//     del_one(&conn,String::from("2021-08-31 14:05"));
// }


// pub fn main1() {
//     let args: Vec<String> = env::args().collect();

//     // The first argument is the path that was used to call the program.
//     println!("My path is {}.", args[0]);

//     // The rest of the arguments are the passed command line parameters.
//     // Call the program like this:
//     //   $ ./args arg1 arg2
//     println!("I got {:?} arguments: {:?}.", args.len() - 1, &args[1..]);
// }

// fn increase(number: i32) {
//     println!("{}", number + 1);
// }

// fn decrease(number: i32) {
//     println!("{}", number - 1);
// }

fn help() {
    println!("usage:
m dec id 
m inc id
m del id
m chg id1 wtb
m cp id1 id2");
}
// fn del_id(id:&str)-> rusqlite::Result<()> {
//     println!("{}",id);
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     del_one(conn,String::from(id));
//     Ok(())
// }
// fn inc_id(id:&str)-> rusqlite::Result<()>{
//     println!("{}",id);
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     change_one(conn,String::from(id),1.0/1.005);
//     Ok(())
// }
// fn dec_id(id:&str)-> rusqlite::Result<()>{
//     println!("{}",id);
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     change_one(conn,String::from(id),1.005);
//     Ok(())
// }
// fn chg_id(id1:&str,id2:&str)-> rusqlite::Result<()>{
//     println!("{},{}",id1,id2);
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     change_one(conn,String::from(id1),id2.parse::<f32>().unwrap());
//     Ok(())
// }
// fn cp_id(id1:&str,id2:&str)-> rusqlite::Result<()>{
//     println!("{},{}",id1,id2);
//     let constr=String::from("c:\\ncs\\ncs_cs\\cs\\data.db");
//     let conn = rusqlite::Connection::open(constr)?;
//     copy_one(conn,String::from(id1),String::from(id2));
//     Ok(())
// }
pub fn main() {
    let args: Vec<String> = env::args().collect();
    match args.len() {
        // no arguments passed
        1 => {
            help();
        },
        // one argument passed
        2 => {
           help();
        },
        // one command and one argument passed
        3 | 4 => {
            let cur_exe=std::env::current_exe().unwrap();
            let root=cur_exe.parent().unwrap();
            let dbfile=root.join("data.db");
            let constr=format!("{}",dbfile.display());
            let conn = rusqlite::Connection::open(constr).unwrap();
            let cmd = &args[1];
            let id1  = &args[2];
            if args.len()==4 {
                let id2  = &args[3];
                match &cmd[..] {
                    "cp" =>{copy_one(&conn,String::from(id1),String::from(id2));},
                    "chg" =>{change_one(&conn,String::from(id1),id2.parse::<f32>().unwrap());},
                    _ => {
                        eprintln!("error: invalid command");
                        help();
                    },
                }                
            }else{
                match &cmd[..] {
                    "inc" => {
                        change_one(&conn,String::from(id1),1.0/1.005);
                    },
                    "dec" => {change_one(&conn,String::from(id1),1.005);},
                    "del" => {del_one(&conn,String::from(id1));},
                    _ => {
                        eprintln!("error: invalid command");
                        help();
                    },
                }
            }
        },
        // all the other cases
        _ => {
            // show a help message
            help();
        }
    }
}

